﻿using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;

namespace bilibili_video_export
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private bool IsAllZeroBytes(byte[] bytes, int startIndex, int count)
        {
            for (int i = startIndex; i < startIndex + count; i++)
            {
                if (bytes[i] != '0')
                {
                    return false;
                }
            }
            return true;
        }

        private void DeleteLeadingZeroBytes(string fileName, int bytesCount)
        {
            try
            {
                byte[] fileBytes = File.ReadAllBytes(fileName);

                if (fileBytes.Length >= bytesCount && IsAllZeroBytes(fileBytes, 0, bytesCount))
                {
                    byte[] newFileBytes = new byte[fileBytes.Length - bytesCount];
                    Array.Copy(fileBytes, bytesCount, newFileBytes, 0, newFileBytes.Length);

                    File.WriteAllBytes(fileName, newFileBytes);
                    Console.WriteLine("已删除文件 {0} 的前 {1} 个字节。", fileName, bytesCount);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("处理文件 {0} 时出错：{1}", fileName, ex.Message);
            }
        }

        private void GetGroupAndTitleFromJson(string jsonFilePath, out string groupTitle, out string title)
        {
            groupTitle = "";
            title = "";

            try
            {
                string json = File.ReadAllText(jsonFilePath);
                JObject jsonObject = JObject.Parse(json);

                groupTitle = (string)jsonObject["groupTitle"];
                title = (string)jsonObject["title"];
            }
            catch (Exception ex)
            {
                Console.WriteLine("读取.videoInfo文件时出错：{0}", ex.Message);
            }
        }

        private void ConvertLchdatToMp4(string directoryPath, string outputFilePath)
        {
            try
            {
                // 获取指定路径下的所有.lchdat文件
                string[] lchdatFiles = Directory.GetFiles(directoryPath, "*.lchdat");

                if (lchdatFiles.Length == 0)
                {
                    Console.WriteLine("指定路径下没有.lchdat文件。");
                    return;
                }

                // 构建ffmpeg命令
                string ffmpegCommand = "C:\\ffmpeg\\bin\\ffmpeg.exe";
                foreach (string lchdatFile in lchdatFiles)
                {
                    ffmpegCommand += " -i \"" + lchdatFile + "\"";
                }
                ffmpegCommand += " -codec copy \"" + outputFilePath + "\"";

                // 调用ffmpeg命令
                ProcessStartInfo processStartInfo = new ProcessStartInfo();
                processStartInfo.FileName = "cmd.exe";
                processStartInfo.RedirectStandardInput = true;
                processStartInfo.UseShellExecute = false;

                Process process = Process.Start(processStartInfo);
                process.StandardInput.WriteLine(ffmpegCommand);
                process.StandardInput.Flush();
                process.StandardInput.Close();
                process.WaitForExit();
            }
            catch (Exception ex)
            {
                Console.WriteLine("转换过程中出现错误：{0}", ex.Message);
            }
        }

        private bool CheckAndCreateFolder(string folderPath)
        {
            try
            {
                if (Directory.Exists(folderPath))
                {
                    return true;
                }
                else
                {
                    Directory.CreateDirectory(folderPath);
                    return true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("创建文件夹时出错：{0}", ex.Message);
                return false;
            }
        }

        // 删除文件夹folderPath下所有后缀为fileExtension的文件
        void DeleteFilesWithExtension(string folderPath, string fileExtension)
        {
            string[] files = Directory.GetFiles(folderPath, "*" + fileExtension);

            foreach (string file in files)
            {
                File.Delete(file);
                Console.WriteLine("已删除文件: " + file);
            }
        }

        private void exchangeButton_Click(object sender, EventArgs e)
        {
            int totals = 0;
            // 获取当前哔哩哔哩文件缓存的路径
            string bibiliPath = inputPathTextBox.Text;
            // 获取输出目录
            string outputPath = outputPathTextBox.Text;
            // 遍历当前目录下的所有子目录
            string[] subDirectories = Directory.GetDirectories(bibiliPath);
            foreach (string currentDirectory in subDirectories)
            {
                //Console.WriteLine("Directory: " + subDirectory);
                string mp4DirPath = outputPath;

                if (!File.Exists(currentDirectory + "\\.videoInfo"))
                {
                    continue;
                }

                // group title和title处理
                string groupTitle, title;
                GetGroupAndTitleFromJson(currentDirectory + "\\.videoInfo",out groupTitle, out title);
                
                string[] files = Directory.GetFiles(currentDirectory, "*.m4s");

                foreach (string file in files)
                {
                    // 复制文件并更改后缀名
                    string newFileName = Path.ChangeExtension(file, ".lchdat");


                    if (File.Exists(newFileName))
                    {
                        File.Delete(newFileName);
                    }
                    File.Copy(file, newFileName);

                    // 删除.lchdat类型文件的前9个字节,这9个字节全是字符'0'。
                    if (Path.GetExtension(newFileName) == ".lchdat")
                    {
                        DeleteLeadingZeroBytes(newFileName, 9);
                    }
                }
                
                // 创建groupTitle目录（只创建一次）
                if (CheckAndCreateFolder(outputPath + "\\" + groupTitle))
                {
                    mp4DirPath = outputPath + "\\" + groupTitle;
                }
                else
                {
                    Console.WriteLine("无法创建文件夹。");
                }

                // 将当前路径currentDirectory下的所有.lchdat后缀的临时文件转为mp4格式
                ConvertLchdatToMp4(currentDirectory, mp4DirPath + "\\" + title+".mp4");

                DeleteFilesWithExtension(currentDirectory, ".lchdat");

                totals += 1;
            }

            MessageBox.Show("转换完成，转换视频个数："+totals, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}
